home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-03-06 | 3.3 KB | 96 lines | [TEXT/GEOL] |
- Item forwarded by MM.XOBJ to D0776 D5543 D3431
-
- Item 3035708 12-Sept-90 12:41PDT
-
- From: MM.XOBJ MacroMind, XObject Support,PRT
-
- To: TIM.SWIHART Swihart, Tim
- CPLUS.DEV$ C++ Interest List--Developers
- CPLUS.APPLE$ C++ Interest List--Apple Employees
-
- Sub: Assignment constructor bug?
-
- Can anyone explain this problem, is it a bug or a feature? I spent a day
- tracking down why a file would not compile. I managed to boil it down to its
- purest form.
-
- Given a function, funcThatTakesAFoo(Foo f), that is passed a Foo by value,
- passing it an object of the derived class, Bar, is also fine. I do this in two
- different contexts:
-
- class Foo { /* .... */ };
- class Bar : public Foo { /* .... */ };
-
- extern void funcThatTakesAFoo(Foo);
-
- void func1()
- {
- Bar b;
-
- funcThatTakesAFoo(b); // this of course, is fine
- }
-
- void func2(Bar b)
- {
- funcThatTakesAFoo(b);
- }
-
-
- With no constructors or default constructors for Foo and Bar, both of these
- functions are fine. If I add a constructor for the derived class of the form
- Bar::Bar(Bar &), however, func1() is still OK, but func2() yields the error:
-
- # error: cannot cast class object to pointer
-
- This error is also generated by the expression:
-
- Foo f = Bar b;
-
- The problem goes away if an assignment constructor styled Foo::Foo(&Foo)
- exists. (Thank you Al McNeil for saving my life!)
-
- Now I know that providing an explicit operator= or assignment constructor
- requires *derived* classes to provide equivalent constructs, since the default
- memberwise assignment is defeated from that point forward. What I don't
- understand is why it seems to be defeated from that point backwards to Foo!
-
- I also don't understand why these two functions which generate nearly identical
- code (the local Bar versus the parameter Bar is of little consequence) stop
- compiling similarly with the introduction of Bar::Bar(Bar&). I have looked at
- the generated output of the successful compiles. Alas, CFront won't generate a
- single line of C for the function if it fails to compile.
-
- It all boils down to two problems:
-
- 1) the existence of Bar::Bar(Bar &) makes “Foo f = Bar b” illegal.
-
- 2) This construct is generated only when I pass a parameter received by value
- to a function that takes its base class by value, when the constructor
- Bar::Bar(Bar &) exists, and not when it doesn't. Why is a temporary variable
- necessary for this.
-
- Fortunately, I own the source code to my equivalent of class Foo, and have
- provided the workaround, but I don't know what I would have done if this were a
- library, and I resent having to change an otherwise stable class.
-
- If this is specified in the language somehow, and if someone can point me to
- the appropriate spot in the AT&T manual, or Lippman, or even the original
- Stroustrup, I would be grateful. (The Annotated C++ Reference seems hard to
- come by on the East coast).
-
- If it is some sort of bug, I would like to know if it is located in CFront or
- subsequent Apple adaptation. There is no reason I know of that using the
- following C output should cease to be correct because of Bar::Bar(Bar &).
-
- struct Foo f;
- struct Bar b;
-
- f = b;
-
- Haim Zamir
- MacroMind, Inc.
- AppleLink MM.XOBJ
-
-
-
-